/*
 * RoboEye - Web client for www.newocr.com that allows you
 * to recognize an image captured by the camera.
 *
 * Copyright (C) Oxygen Development, 2011
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package com.devoxy.roboeye.core.service;

import android.app.IntentService;
import android.content.Intent;
import android.os.Bundle;
import com.devoxy.roboeye.R;
import com.devoxy.roboeye.core.FileHelper;
import com.devoxy.roboeye.core.http.HttpHelper;
import com.devoxy.roboeye.core.provider.EntityManager;
import com.devoxy.roboeye.core.provider.Task;
import com.devoxy.roboeye.global.IntentHelper;
import com.devoxy.roboeye.global.PreferencesHelper;
import com.devoxy.roboeye.global.exceptions.IntentException;
import com.devoxy.roboeye.global.log.Log;
import com.devoxy.roboeye.ui.NotificationHelper;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.UnknownHostException;

/**
 * Created by Oxygen Development.
 * Author: Dmitriy Tarasov (dm.vl.tarasov@gmail.com)
 * Date: 11.06.11
 * Time: 0:08
 */
public class RoboEyeService extends IntentService {

    private static final String TAG = IntentService.class.getName();
    private static final String WORKER_THREAD_NAME = "RoboEye_Service_Thread";

    private Thread worker; // our thread that sends photos to server and receive the results

    public RoboEyeService() {
        super(WORKER_THREAD_NAME);
        Log.i(TAG, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>> initialize service");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, ">>>>>>>>>>>>>>>>>>>>>> onCreate");

        worker = new Thread(new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, ">>>>>>>>>>>>> worker started");
                doWork();
                stopSelf();
                Log.i(TAG, ">>>>>>>>>>>>> worker finished");
            }
        });
    }

    private void doWork() {
        Task task;
        while ((task = EntityManager.getFirstTask()) != null) { // do while have tasks
            try {
                EntityManager.markTaskAsStarted(task);
                if (task.getType()) { // directory
                    processFolder(task);
                } else { // single image
                    processSingleImage(task.getSource(), task.getTarget(), task.getLanguage(), task.getRotation());
                }
                EntityManager.markTaskAsFinished(task);
                Boolean notificationsEnabled = PreferencesHelper.getPref(R.string.notification_pref);
                if (notificationsEnabled) {
                    NotificationHelper.taskFinished(task);
                }
            } catch (UnknownHostException e) { // internet connection problems
                EntityManager.markTaskAsNotStarted(task);
                Log.e(TAG, "cannot connect to newocr.com", e);
            } catch (IOException e) {
                Log.e(TAG, "cannot save result to file", e);
            }
        }
    }

    private void processFolder(Task task) throws IOException {
        File dir = new File(task.getSource());
        File[] images = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return FileHelper.isImage(pathname);
            }
        });
        for (File f : images) {
            processSingleImage(f.getName(), FileHelper.getTxtFileName(f.getName()), task.getLanguage(), task.getRotation());
        }
    }

    private void processSingleImage(String source, String target, String language, String rotate) throws IOException {
        String result = HttpHelper.processImage(source, language, rotate);
        if (result != null) {
            FileHelper.saveToFile(result, target);
        }
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i(TAG, "new intent received " + intent);
        if (IntentHelper.ACTION_ADD_TASK.equals(intent.getAction())) {
            handleAddTaskIntent(intent);
        } else if (IntentHelper.ACTION_CANCEL_TASK.equals(intent.getAction())) {
            handleCancelTaskIntent(intent);
        } else if (IntentHelper.ACTION_CANCEL_ALL.equals(intent.getAction())) {
            handleCancelAllIntent();
        } else if (IntentHelper.ACTION_CLEAR_FINISHED.equals(intent.getAction())) {
            handleClearFinishedIntent();
        } else {
            throw new IntentException("unknown intent with action = " + intent.getAction());
        }
    }

    private void handleClearFinishedIntent() {
        EntityManager.clearFinishedTasks();
    }

    private void handleCancelAllIntent() {
        EntityManager.cancelAllTasks();
    }

    private void handleCancelTaskIntent(Intent intent) {
        Task task = new Task();
        task.setId(intent.getLongExtra(Task._ID, 0));
        EntityManager.deleteTask(task);
    }

    private void handleAddTaskIntent(Intent intent) {
        Task task = new Task();
        Bundle extras = intent.getExtras();
        task.setType(extras.getBoolean(Task.TYPE));
        task.setSource(extras.getString(Task.SOURCE));
        task.setTarget(extras.getString(Task.TARGET));
        task.setLanguage(extras.getString(Task.LANGUAGE));
        task.setRotation(extras.getString(Task.ROTATION));
        EntityManager.createTask(task);

        // start worker thread if need
        if (worker.getState() != Thread.State.RUNNABLE) {
            worker.start();
        }
    }

}
